// $ANTLR 3.0.1 C:\\Users\\Derek\\workspace\\CS-214-Interpreters\\src\\edu\\calvin\\djs32\\cs214\\interpreters\\frontend\\Hobbes2008.g 2008-04-11 10:51:29

package edu.calvin.djs32.cs214.interpreters.frontend;


import org.antlr.runtime.*;
import java.util.Stack;
import java.util.List;
import java.util.ArrayList;


import org.antlr.runtime.tree.*;

@SuppressWarnings("all")
public class Hobbes2008Parser extends Parser {
    public static final String[] tokenNames = new String[] {
        "<invalid>", "<EOR>", "<DOWN>", "<UP>", "TUPLE", "APPLICATION", "IF", "ELSE", "THEN", "END", "LET", "IN", "KEYWORD", "NUMBER", "HEXDIGIT", "SIGN", "INTEGER", "IDENTIFIER", "WHITESPACE", "COMMENTS", "STRING", "COMMA", "LPAREN", "RPAREN"
    };
    public static final int COMMA=21;
    public static final int HEXDIGIT=14;
    public static final int END=9;
    public static final int APPLICATION=5;
    public static final int KEYWORD=12;
    public static final int NUMBER=13;
    public static final int STRING=20;
    public static final int THEN=8;
    public static final int TUPLE=4;
    public static final int COMMENTS=19;
    public static final int WHITESPACE=18;
    public static final int IN=11;
    public static final int INTEGER=16;
    public static final int ELSE=7;
    public static final int IF=6;
    public static final int LET=10;
    public static final int EOF=-1;
    public static final int RPAREN=23;
    public static final int LPAREN=22;
    public static final int SIGN=15;
    public static final int IDENTIFIER=17;

        public Hobbes2008Parser(TokenStream input) {
            super(input);
        }
        
    protected TreeAdaptor adaptor = new CommonTreeAdaptor();

    public void setTreeAdaptor(TreeAdaptor adaptor) {
        this.adaptor = adaptor;
    }
    public TreeAdaptor getTreeAdaptor() {
        return adaptor;
    }

    public String[] getTokenNames() { return tokenNames; }
    public String getGrammarFileName() { return "C:\\Users\\Derek\\workspace\\CS-214-Interpreters\\src\\edu\\calvin\\djs32\\cs214\\interpreters\\frontend\\Hobbes2008.g"; }

     
      protected void mismatch(IntStream input, int ttype, BitSet follow) 
        throws RecognitionException { 
        throw new MismatchedTokenException(ttype, input); 
      } 
      public void recoverFromMismatchedSet(IntStream input, RecognitionException e, BitSet follow) 
        throws RecognitionException { 
        throw e; 
      } 


    public static class program_return extends ParserRuleReturnScope {
        Object tree;
        public Object getTree() { return tree; }
    };

    // $ANTLR start program
    // C:\\Users\\Derek\\workspace\\CS-214-Interpreters\\src\\edu\\calvin\\djs32\\cs214\\interpreters\\frontend\\Hobbes2008.g:57:1: program : expression EOF ;
    public final program_return program() throws RecognitionException {
        program_return retval = new program_return();
        retval.start = input.LT(1);

        Object root_0 = null;

        Token EOF2=null;
        expression_return expression1 = null;


        Object EOF2_tree=null;

        try {
            // C:\\Users\\Derek\\workspace\\CS-214-Interpreters\\src\\edu\\calvin\\djs32\\cs214\\interpreters\\frontend\\Hobbes2008.g:57:8: ( expression EOF )
            // C:\\Users\\Derek\\workspace\\CS-214-Interpreters\\src\\edu\\calvin\\djs32\\cs214\\interpreters\\frontend\\Hobbes2008.g:57:10: expression EOF
            {
            root_0 = (Object)adaptor.nil();

            pushFollow(FOLLOW_expression_in_program127);
            expression1=expression();
            _fsp--;

            adaptor.addChild(root_0, expression1.getTree());
            EOF2=(Token)input.LT(1);
            match(input,EOF,FOLLOW_EOF_in_program129); 

            }

            retval.stop = input.LT(-1);

                retval.tree = (Object)adaptor.rulePostProcessing(root_0);
                adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);

        }
         
          catch (RecognitionException e) { 
            throw e; 
          } 
        finally {
        }
        return retval;
    }
    // $ANTLR end program

    public static class expression_return extends ParserRuleReturnScope {
        Object tree;
        public Object getTree() { return tree; }
    };

    // $ANTLR start expression
    // C:\\Users\\Derek\\workspace\\CS-214-Interpreters\\src\\edu\\calvin\\djs32\\cs214\\interpreters\\frontend\\Hobbes2008.g:86:1: expression : ( INTEGER | STRING | tuple | application | ife | identifier | let );
    public final expression_return expression() throws RecognitionException {
        expression_return retval = new expression_return();
        retval.start = input.LT(1);

        Object root_0 = null;

        Token INTEGER3=null;
        Token STRING4=null;
        tuple_return tuple5 = null;

        application_return application6 = null;

        ife_return ife7 = null;

        identifier_return identifier8 = null;

        let_return let9 = null;


        Object INTEGER3_tree=null;
        Object STRING4_tree=null;

        try {
            // C:\\Users\\Derek\\workspace\\CS-214-Interpreters\\src\\edu\\calvin\\djs32\\cs214\\interpreters\\frontend\\Hobbes2008.g:86:13: ( INTEGER | STRING | tuple | application | ife | identifier | let )
            int alt1=7;
            switch ( input.LA(1) ) {
            case INTEGER:
                {
                alt1=1;
                }
                break;
            case STRING:
                {
                alt1=2;
                }
                break;
            case LPAREN:
                {
                alt1=3;
                }
                break;
            case IDENTIFIER:
                {
                int LA1_4 = input.LA(2);

                if ( (LA1_4==LPAREN) ) {
                    alt1=4;
                }
                else if ( (LA1_4==EOF||(LA1_4>=ELSE && LA1_4<=END)||LA1_4==IN||LA1_4==COMMA||LA1_4==RPAREN) ) {
                    alt1=6;
                }
                else {
                    NoViableAltException nvae =
                        new NoViableAltException("86:1: expression : ( INTEGER | STRING | tuple | application | ife | identifier | let );", 1, 4, input);

                    throw nvae;
                }
                }
                break;
            case IF:
                {
                alt1=5;
                }
                break;
            case LET:
                {
                alt1=7;
                }
                break;
            default:
                NoViableAltException nvae =
                    new NoViableAltException("86:1: expression : ( INTEGER | STRING | tuple | application | ife | identifier | let );", 1, 0, input);

                throw nvae;
            }

            switch (alt1) {
                case 1 :
                    // C:\\Users\\Derek\\workspace\\CS-214-Interpreters\\src\\edu\\calvin\\djs32\\cs214\\interpreters\\frontend\\Hobbes2008.g:86:21: INTEGER
                    {
                    root_0 = (Object)adaptor.nil();

                    INTEGER3=(Token)input.LT(1);
                    match(input,INTEGER,FOLLOW_INTEGER_in_expression496); 
                    INTEGER3_tree = (Object)adaptor.create(INTEGER3);
                    adaptor.addChild(root_0, INTEGER3_tree);


                    }
                    break;
                case 2 :
                    // C:\\Users\\Derek\\workspace\\CS-214-Interpreters\\src\\edu\\calvin\\djs32\\cs214\\interpreters\\frontend\\Hobbes2008.g:86:31: STRING
                    {
                    root_0 = (Object)adaptor.nil();

                    STRING4=(Token)input.LT(1);
                    match(input,STRING,FOLLOW_STRING_in_expression500); 
                    STRING4_tree = (Object)adaptor.create(STRING4);
                    adaptor.addChild(root_0, STRING4_tree);


                    }
                    break;
                case 3 :
                    // C:\\Users\\Derek\\workspace\\CS-214-Interpreters\\src\\edu\\calvin\\djs32\\cs214\\interpreters\\frontend\\Hobbes2008.g:86:40: tuple
                    {
                    root_0 = (Object)adaptor.nil();

                    pushFollow(FOLLOW_tuple_in_expression504);
                    tuple5=tuple();
                    _fsp--;

                    adaptor.addChild(root_0, tuple5.getTree());

                    }
                    break;
                case 4 :
                    // C:\\Users\\Derek\\workspace\\CS-214-Interpreters\\src\\edu\\calvin\\djs32\\cs214\\interpreters\\frontend\\Hobbes2008.g:86:48: application
                    {
                    root_0 = (Object)adaptor.nil();

                    pushFollow(FOLLOW_application_in_expression508);
                    application6=application();
                    _fsp--;

                    adaptor.addChild(root_0, application6.getTree());

                    }
                    break;
                case 5 :
                    // C:\\Users\\Derek\\workspace\\CS-214-Interpreters\\src\\edu\\calvin\\djs32\\cs214\\interpreters\\frontend\\Hobbes2008.g:86:62: ife
                    {
                    root_0 = (Object)adaptor.nil();

                    pushFollow(FOLLOW_ife_in_expression512);
                    ife7=ife();
                    _fsp--;

                    adaptor.addChild(root_0, ife7.getTree());

                    }
                    break;
                case 6 :
                    // C:\\Users\\Derek\\workspace\\CS-214-Interpreters\\src\\edu\\calvin\\djs32\\cs214\\interpreters\\frontend\\Hobbes2008.g:86:68: identifier
                    {
                    root_0 = (Object)adaptor.nil();

                    pushFollow(FOLLOW_identifier_in_expression516);
                    identifier8=identifier();
                    _fsp--;

                    adaptor.addChild(root_0, identifier8.getTree());

                    }
                    break;
                case 7 :
                    // C:\\Users\\Derek\\workspace\\CS-214-Interpreters\\src\\edu\\calvin\\djs32\\cs214\\interpreters\\frontend\\Hobbes2008.g:86:81: let
                    {
                    root_0 = (Object)adaptor.nil();

                    pushFollow(FOLLOW_let_in_expression520);
                    let9=let();
                    _fsp--;

                    adaptor.addChild(root_0, let9.getTree());

                    }
                    break;

            }
            retval.stop = input.LT(-1);

                retval.tree = (Object)adaptor.rulePostProcessing(root_0);
                adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);

        }
         
          catch (RecognitionException e) { 
            throw e; 
          } 
        finally {
        }
        return retval;
    }
    // $ANTLR end expression

    public static class application_return extends ParserRuleReturnScope {
        Object tree;
        public Object getTree() { return tree; }
    };

    // $ANTLR start application
    // C:\\Users\\Derek\\workspace\\CS-214-Interpreters\\src\\edu\\calvin\\djs32\\cs214\\interpreters\\frontend\\Hobbes2008.g:87:1: application : identifier tuple -> ^( APPLICATION identifier tuple ) ;
    public final application_return application() throws RecognitionException {
        application_return retval = new application_return();
        retval.start = input.LT(1);

        Object root_0 = null;

        identifier_return identifier10 = null;

        tuple_return tuple11 = null;


        RewriteRuleSubtreeStream stream_identifier=new RewriteRuleSubtreeStream(adaptor,"rule identifier");
        RewriteRuleSubtreeStream stream_tuple=new RewriteRuleSubtreeStream(adaptor,"rule tuple");
        try {
            // C:\\Users\\Derek\\workspace\\CS-214-Interpreters\\src\\edu\\calvin\\djs32\\cs214\\interpreters\\frontend\\Hobbes2008.g:87:13: ( identifier tuple -> ^( APPLICATION identifier tuple ) )
            // C:\\Users\\Derek\\workspace\\CS-214-Interpreters\\src\\edu\\calvin\\djs32\\cs214\\interpreters\\frontend\\Hobbes2008.g:87:15: identifier tuple
            {
            pushFollow(FOLLOW_identifier_in_application527);
            identifier10=identifier();
            _fsp--;

            stream_identifier.add(identifier10.getTree());
            pushFollow(FOLLOW_tuple_in_application529);
            tuple11=tuple();
            _fsp--;

            stream_tuple.add(tuple11.getTree());

            // AST REWRITE
            // elements: identifier, tuple
            // token labels: 
            // rule labels: retval
            // token list labels: 
            // rule list labels: 
            retval.tree = root_0;
            RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"token retval",retval!=null?retval.tree:null);

            root_0 = (Object)adaptor.nil();
            // 87:32: -> ^( APPLICATION identifier tuple )
            {
                // C:\\Users\\Derek\\workspace\\CS-214-Interpreters\\src\\edu\\calvin\\djs32\\cs214\\interpreters\\frontend\\Hobbes2008.g:87:35: ^( APPLICATION identifier tuple )
                {
                Object root_1 = (Object)adaptor.nil();
                root_1 = (Object)adaptor.becomeRoot(adaptor.create(APPLICATION, "APPLICATION"), root_1);

                adaptor.addChild(root_1, stream_identifier.next());
                adaptor.addChild(root_1, stream_tuple.next());

                adaptor.addChild(root_0, root_1);
                }

            }



            }

            retval.stop = input.LT(-1);

                retval.tree = (Object)adaptor.rulePostProcessing(root_0);
                adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);

        }
         
          catch (RecognitionException e) { 
            throw e; 
          } 
        finally {
        }
        return retval;
    }
    // $ANTLR end application

    public static class identifier_return extends ParserRuleReturnScope {
        Object tree;
        public Object getTree() { return tree; }
    };

    // $ANTLR start identifier
    // C:\\Users\\Derek\\workspace\\CS-214-Interpreters\\src\\edu\\calvin\\djs32\\cs214\\interpreters\\frontend\\Hobbes2008.g:88:1: identifier : IDENTIFIER ;
    public final identifier_return identifier() throws RecognitionException {
        identifier_return retval = new identifier_return();
        retval.start = input.LT(1);

        Object root_0 = null;

        Token IDENTIFIER12=null;

        Object IDENTIFIER12_tree=null;

        try {
            // C:\\Users\\Derek\\workspace\\CS-214-Interpreters\\src\\edu\\calvin\\djs32\\cs214\\interpreters\\frontend\\Hobbes2008.g:88:12: ( IDENTIFIER )
            // C:\\Users\\Derek\\workspace\\CS-214-Interpreters\\src\\edu\\calvin\\djs32\\cs214\\interpreters\\frontend\\Hobbes2008.g:88:14: IDENTIFIER
            {
            root_0 = (Object)adaptor.nil();

            IDENTIFIER12=(Token)input.LT(1);
            match(input,IDENTIFIER,FOLLOW_IDENTIFIER_in_identifier546); 
            IDENTIFIER12_tree = (Object)adaptor.create(IDENTIFIER12);
            adaptor.addChild(root_0, IDENTIFIER12_tree);


            }

            retval.stop = input.LT(-1);

                retval.tree = (Object)adaptor.rulePostProcessing(root_0);
                adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);

        }
         
          catch (RecognitionException e) { 
            throw e; 
          } 
        finally {
        }
        return retval;
    }
    // $ANTLR end identifier

    public static class let_return extends ParserRuleReturnScope {
        Object tree;
        public Object getTree() { return tree; }
    };

    // $ANTLR start let
    // C:\\Users\\Derek\\workspace\\CS-214-Interpreters\\src\\edu\\calvin\\djs32\\cs214\\interpreters\\frontend\\Hobbes2008.g:89:1: let : LET identifier KEYWORD expression IN expression -> ^( LET identifier expression expression ) ;
    public final let_return let() throws RecognitionException {
        let_return retval = new let_return();
        retval.start = input.LT(1);

        Object root_0 = null;

        Token LET13=null;
        Token KEYWORD15=null;
        Token IN17=null;
        identifier_return identifier14 = null;

        expression_return expression16 = null;

        expression_return expression18 = null;


        Object LET13_tree=null;
        Object KEYWORD15_tree=null;
        Object IN17_tree=null;
        RewriteRuleTokenStream stream_LET=new RewriteRuleTokenStream(adaptor,"token LET");
        RewriteRuleTokenStream stream_KEYWORD=new RewriteRuleTokenStream(adaptor,"token KEYWORD");
        RewriteRuleTokenStream stream_IN=new RewriteRuleTokenStream(adaptor,"token IN");
        RewriteRuleSubtreeStream stream_identifier=new RewriteRuleSubtreeStream(adaptor,"rule identifier");
        RewriteRuleSubtreeStream stream_expression=new RewriteRuleSubtreeStream(adaptor,"rule expression");
        try {
            // C:\\Users\\Derek\\workspace\\CS-214-Interpreters\\src\\edu\\calvin\\djs32\\cs214\\interpreters\\frontend\\Hobbes2008.g:89:6: ( LET identifier KEYWORD expression IN expression -> ^( LET identifier expression expression ) )
            // C:\\Users\\Derek\\workspace\\CS-214-Interpreters\\src\\edu\\calvin\\djs32\\cs214\\interpreters\\frontend\\Hobbes2008.g:89:8: LET identifier KEYWORD expression IN expression
            {
            LET13=(Token)input.LT(1);
            match(input,LET,FOLLOW_LET_in_let554); 
            stream_LET.add(LET13);

            pushFollow(FOLLOW_identifier_in_let556);
            identifier14=identifier();
            _fsp--;

            stream_identifier.add(identifier14.getTree());
            KEYWORD15=(Token)input.LT(1);
            match(input,KEYWORD,FOLLOW_KEYWORD_in_let558); 
            stream_KEYWORD.add(KEYWORD15);

            pushFollow(FOLLOW_expression_in_let560);
            expression16=expression();
            _fsp--;

            stream_expression.add(expression16.getTree());
            IN17=(Token)input.LT(1);
            match(input,IN,FOLLOW_IN_in_let562); 
            stream_IN.add(IN17);

            pushFollow(FOLLOW_expression_in_let564);
            expression18=expression();
            _fsp--;

            stream_expression.add(expression18.getTree());

            // AST REWRITE
            // elements: expression, expression, identifier, LET
            // token labels: 
            // rule labels: retval
            // token list labels: 
            // rule list labels: 
            retval.tree = root_0;
            RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"token retval",retval!=null?retval.tree:null);

            root_0 = (Object)adaptor.nil();
            // 89:56: -> ^( LET identifier expression expression )
            {
                // C:\\Users\\Derek\\workspace\\CS-214-Interpreters\\src\\edu\\calvin\\djs32\\cs214\\interpreters\\frontend\\Hobbes2008.g:89:59: ^( LET identifier expression expression )
                {
                Object root_1 = (Object)adaptor.nil();
                root_1 = (Object)adaptor.becomeRoot(stream_LET.next(), root_1);

                adaptor.addChild(root_1, stream_identifier.next());
                adaptor.addChild(root_1, stream_expression.next());
                adaptor.addChild(root_1, stream_expression.next());

                adaptor.addChild(root_0, root_1);
                }

            }



            }

            retval.stop = input.LT(-1);

                retval.tree = (Object)adaptor.rulePostProcessing(root_0);
                adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);

        }
         
          catch (RecognitionException e) { 
            throw e; 
          } 
        finally {
        }
        return retval;
    }
    // $ANTLR end let

    public static class ife_return extends ParserRuleReturnScope {
        Object tree;
        public Object getTree() { return tree; }
    };

    // $ANTLR start ife
    // C:\\Users\\Derek\\workspace\\CS-214-Interpreters\\src\\edu\\calvin\\djs32\\cs214\\interpreters\\frontend\\Hobbes2008.g:90:1: ife : IF expression THEN expression ELSE expression END -> ^( IF ( expression )* ) ;
    public final ife_return ife() throws RecognitionException {
        ife_return retval = new ife_return();
        retval.start = input.LT(1);

        Object root_0 = null;

        Token IF19=null;
        Token THEN21=null;
        Token ELSE23=null;
        Token END25=null;
        expression_return expression20 = null;

        expression_return expression22 = null;

        expression_return expression24 = null;


        Object IF19_tree=null;
        Object THEN21_tree=null;
        Object ELSE23_tree=null;
        Object END25_tree=null;
        RewriteRuleTokenStream stream_THEN=new RewriteRuleTokenStream(adaptor,"token THEN");
        RewriteRuleTokenStream stream_ELSE=new RewriteRuleTokenStream(adaptor,"token ELSE");
        RewriteRuleTokenStream stream_END=new RewriteRuleTokenStream(adaptor,"token END");
        RewriteRuleTokenStream stream_IF=new RewriteRuleTokenStream(adaptor,"token IF");
        RewriteRuleSubtreeStream stream_expression=new RewriteRuleSubtreeStream(adaptor,"rule expression");
        try {
            // C:\\Users\\Derek\\workspace\\CS-214-Interpreters\\src\\edu\\calvin\\djs32\\cs214\\interpreters\\frontend\\Hobbes2008.g:90:6: ( IF expression THEN expression ELSE expression END -> ^( IF ( expression )* ) )
            // C:\\Users\\Derek\\workspace\\CS-214-Interpreters\\src\\edu\\calvin\\djs32\\cs214\\interpreters\\frontend\\Hobbes2008.g:90:8: IF expression THEN expression ELSE expression END
            {
            IF19=(Token)input.LT(1);
            match(input,IF,FOLLOW_IF_in_ife584); 
            stream_IF.add(IF19);

            pushFollow(FOLLOW_expression_in_ife586);
            expression20=expression();
            _fsp--;

            stream_expression.add(expression20.getTree());
            THEN21=(Token)input.LT(1);
            match(input,THEN,FOLLOW_THEN_in_ife588); 
            stream_THEN.add(THEN21);

            pushFollow(FOLLOW_expression_in_ife590);
            expression22=expression();
            _fsp--;

            stream_expression.add(expression22.getTree());
            ELSE23=(Token)input.LT(1);
            match(input,ELSE,FOLLOW_ELSE_in_ife592); 
            stream_ELSE.add(ELSE23);

            pushFollow(FOLLOW_expression_in_ife594);
            expression24=expression();
            _fsp--;

            stream_expression.add(expression24.getTree());
            END25=(Token)input.LT(1);
            match(input,END,FOLLOW_END_in_ife596); 
            stream_END.add(END25);


            // AST REWRITE
            // elements: expression, IF
            // token labels: 
            // rule labels: retval
            // token list labels: 
            // rule list labels: 
            retval.tree = root_0;
            RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"token retval",retval!=null?retval.tree:null);

            root_0 = (Object)adaptor.nil();
            // 90:58: -> ^( IF ( expression )* )
            {
                // C:\\Users\\Derek\\workspace\\CS-214-Interpreters\\src\\edu\\calvin\\djs32\\cs214\\interpreters\\frontend\\Hobbes2008.g:90:61: ^( IF ( expression )* )
                {
                Object root_1 = (Object)adaptor.nil();
                root_1 = (Object)adaptor.becomeRoot(stream_IF.next(), root_1);

                // C:\\Users\\Derek\\workspace\\CS-214-Interpreters\\src\\edu\\calvin\\djs32\\cs214\\interpreters\\frontend\\Hobbes2008.g:90:66: ( expression )*
                while ( stream_expression.hasNext() ) {
                    adaptor.addChild(root_1, stream_expression.next());

                }
                stream_expression.reset();

                adaptor.addChild(root_0, root_1);
                }

            }



            }

            retval.stop = input.LT(-1);

                retval.tree = (Object)adaptor.rulePostProcessing(root_0);
                adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);

        }
         
          catch (RecognitionException e) { 
            throw e; 
          } 
        finally {
        }
        return retval;
    }
    // $ANTLR end ife

    public static class tuple_return extends ParserRuleReturnScope {
        Object tree;
        public Object getTree() { return tree; }
    };

    // $ANTLR start tuple
    // C:\\Users\\Derek\\workspace\\CS-214-Interpreters\\src\\edu\\calvin\\djs32\\cs214\\interpreters\\frontend\\Hobbes2008.g:91:1: tuple : LPAREN ( expression ( COMMA expression )* )? RPAREN -> ^( TUPLE ( expression )* ) ;
    public final tuple_return tuple() throws RecognitionException {
        tuple_return retval = new tuple_return();
        retval.start = input.LT(1);

        Object root_0 = null;

        Token LPAREN26=null;
        Token COMMA28=null;
        Token RPAREN30=null;
        expression_return expression27 = null;

        expression_return expression29 = null;


        Object LPAREN26_tree=null;
        Object COMMA28_tree=null;
        Object RPAREN30_tree=null;
        RewriteRuleTokenStream stream_COMMA=new RewriteRuleTokenStream(adaptor,"token COMMA");
        RewriteRuleTokenStream stream_RPAREN=new RewriteRuleTokenStream(adaptor,"token RPAREN");
        RewriteRuleTokenStream stream_LPAREN=new RewriteRuleTokenStream(adaptor,"token LPAREN");
        RewriteRuleSubtreeStream stream_expression=new RewriteRuleSubtreeStream(adaptor,"rule expression");
        try {
            // C:\\Users\\Derek\\workspace\\CS-214-Interpreters\\src\\edu\\calvin\\djs32\\cs214\\interpreters\\frontend\\Hobbes2008.g:91:8: ( LPAREN ( expression ( COMMA expression )* )? RPAREN -> ^( TUPLE ( expression )* ) )
            // C:\\Users\\Derek\\workspace\\CS-214-Interpreters\\src\\edu\\calvin\\djs32\\cs214\\interpreters\\frontend\\Hobbes2008.g:91:10: LPAREN ( expression ( COMMA expression )* )? RPAREN
            {
            LPAREN26=(Token)input.LT(1);
            match(input,LPAREN,FOLLOW_LPAREN_in_tuple613); 
            stream_LPAREN.add(LPAREN26);

            // C:\\Users\\Derek\\workspace\\CS-214-Interpreters\\src\\edu\\calvin\\djs32\\cs214\\interpreters\\frontend\\Hobbes2008.g:91:17: ( expression ( COMMA expression )* )?
            int alt3=2;
            int LA3_0 = input.LA(1);

            if ( (LA3_0==IF||LA3_0==LET||(LA3_0>=INTEGER && LA3_0<=IDENTIFIER)||LA3_0==STRING||LA3_0==LPAREN) ) {
                alt3=1;
            }
            switch (alt3) {
                case 1 :
                    // C:\\Users\\Derek\\workspace\\CS-214-Interpreters\\src\\edu\\calvin\\djs32\\cs214\\interpreters\\frontend\\Hobbes2008.g:91:18: expression ( COMMA expression )*
                    {
                    pushFollow(FOLLOW_expression_in_tuple616);
                    expression27=expression();
                    _fsp--;

                    stream_expression.add(expression27.getTree());
                    // C:\\Users\\Derek\\workspace\\CS-214-Interpreters\\src\\edu\\calvin\\djs32\\cs214\\interpreters\\frontend\\Hobbes2008.g:91:29: ( COMMA expression )*
                    loop2:
                    do {
                        int alt2=2;
                        int LA2_0 = input.LA(1);

                        if ( (LA2_0==COMMA) ) {
                            alt2=1;
                        }


                        switch (alt2) {
                    	case 1 :
                    	    // C:\\Users\\Derek\\workspace\\CS-214-Interpreters\\src\\edu\\calvin\\djs32\\cs214\\interpreters\\frontend\\Hobbes2008.g:91:30: COMMA expression
                    	    {
                    	    COMMA28=(Token)input.LT(1);
                    	    match(input,COMMA,FOLLOW_COMMA_in_tuple619); 
                    	    stream_COMMA.add(COMMA28);

                    	    pushFollow(FOLLOW_expression_in_tuple621);
                    	    expression29=expression();
                    	    _fsp--;

                    	    stream_expression.add(expression29.getTree());

                    	    }
                    	    break;

                    	default :
                    	    break loop2;
                        }
                    } while (true);


                    }
                    break;

            }

            RPAREN30=(Token)input.LT(1);
            match(input,RPAREN,FOLLOW_RPAREN_in_tuple627); 
            stream_RPAREN.add(RPAREN30);


            // AST REWRITE
            // elements: expression
            // token labels: 
            // rule labels: retval
            // token list labels: 
            // rule list labels: 
            retval.tree = root_0;
            RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"token retval",retval!=null?retval.tree:null);

            root_0 = (Object)adaptor.nil();
            // 91:58: -> ^( TUPLE ( expression )* )
            {
                // C:\\Users\\Derek\\workspace\\CS-214-Interpreters\\src\\edu\\calvin\\djs32\\cs214\\interpreters\\frontend\\Hobbes2008.g:91:61: ^( TUPLE ( expression )* )
                {
                Object root_1 = (Object)adaptor.nil();
                root_1 = (Object)adaptor.becomeRoot(adaptor.create(TUPLE, "TUPLE"), root_1);

                // C:\\Users\\Derek\\workspace\\CS-214-Interpreters\\src\\edu\\calvin\\djs32\\cs214\\interpreters\\frontend\\Hobbes2008.g:91:69: ( expression )*
                while ( stream_expression.hasNext() ) {
                    adaptor.addChild(root_1, stream_expression.next());

                }
                stream_expression.reset();

                adaptor.addChild(root_0, root_1);
                }

            }



            }

            retval.stop = input.LT(-1);

                retval.tree = (Object)adaptor.rulePostProcessing(root_0);
                adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);

        }
         
          catch (RecognitionException e) { 
            throw e; 
          } 
        finally {
        }
        return retval;
    }
    // $ANTLR end tuple


 

    public static final BitSet FOLLOW_expression_in_program127 = new BitSet(new long[]{0x0000000000000000L});
    public static final BitSet FOLLOW_EOF_in_program129 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_INTEGER_in_expression496 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_STRING_in_expression500 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_tuple_in_expression504 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_application_in_expression508 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_ife_in_expression512 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_identifier_in_expression516 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_let_in_expression520 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_identifier_in_application527 = new BitSet(new long[]{0x0000000000400000L});
    public static final BitSet FOLLOW_tuple_in_application529 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_IDENTIFIER_in_identifier546 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_LET_in_let554 = new BitSet(new long[]{0x0000000000020000L});
    public static final BitSet FOLLOW_identifier_in_let556 = new BitSet(new long[]{0x0000000000001000L});
    public static final BitSet FOLLOW_KEYWORD_in_let558 = new BitSet(new long[]{0x0000000000530440L});
    public static final BitSet FOLLOW_expression_in_let560 = new BitSet(new long[]{0x0000000000000800L});
    public static final BitSet FOLLOW_IN_in_let562 = new BitSet(new long[]{0x0000000000530440L});
    public static final BitSet FOLLOW_expression_in_let564 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_IF_in_ife584 = new BitSet(new long[]{0x0000000000530440L});
    public static final BitSet FOLLOW_expression_in_ife586 = new BitSet(new long[]{0x0000000000000100L});
    public static final BitSet FOLLOW_THEN_in_ife588 = new BitSet(new long[]{0x0000000000530440L});
    public static final BitSet FOLLOW_expression_in_ife590 = new BitSet(new long[]{0x0000000000000080L});
    public static final BitSet FOLLOW_ELSE_in_ife592 = new BitSet(new long[]{0x0000000000530440L});
    public static final BitSet FOLLOW_expression_in_ife594 = new BitSet(new long[]{0x0000000000000200L});
    public static final BitSet FOLLOW_END_in_ife596 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_LPAREN_in_tuple613 = new BitSet(new long[]{0x0000000000D30440L});
    public static final BitSet FOLLOW_expression_in_tuple616 = new BitSet(new long[]{0x0000000000A00000L});
    public static final BitSet FOLLOW_COMMA_in_tuple619 = new BitSet(new long[]{0x0000000000530440L});
    public static final BitSet FOLLOW_expression_in_tuple621 = new BitSet(new long[]{0x0000000000A00000L});
    public static final BitSet FOLLOW_RPAREN_in_tuple627 = new BitSet(new long[]{0x0000000000000002L});

}